﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Data.OleDb;

namespace FlyShop
{
    public partial class FrmRealizaVenda : Form
    {

        // Componentes da conexão
        OleDbConnection conexao;
        String strConexao = "Provider=MSDAORA.1;Data Source=localhost;User ID=pi;Password=pi";

        double descontoFixoClienteEspecial = 99.00;

        int codVooSelecionado;
        int codUsuarioVenda;

        // Inicialmente o codCliente é -1, 
        // assim é possível fazer a validação para saber se um cliente foi selecionado ou não
        public int codClienteVenda = -1;

        public bool clienteEspecial;

        double valorVenda;
        double descontoPromocao;

        String sqlConsultaPromocoesAtivas = "select * from promocao where flag_ativo = 's'";
        String sqlConsultaPromocaoID = "select * from promocao where cod_promocao = ?";
        String sqlConsultaFormasPagamento = "select * from formapagamento";
        String sqlInsereVenda = "insert into venda (cod_venda, num_assento, cod_forma_pagamento, valor, flag_cancelada, cod_cliente, cod_usuario, cod_voo, cod_promocao) values ((select nvl(max(cod_venda), 0) + 1 from venda), ?, ?, ?, ?, ?, ?, ?, ?)";
        String sqlUpdateQntAssentosVoo = "update voo set assentos_disponiveis = (select assentos_disponiveis - 1 from voo where cod_voo = ?) where cod_voo = ?";

        public FrmRealizaVenda()
        {
            InitializeComponent();
        }

       

        private void FrmVenda_Load(object sender, EventArgs e)
        {
            // Estabelece conexão
            conexao = new OleDbConnection(strConexao);
            conexao.Open();


            // Popula a combo de promocoes
            OleDbCommand comandoConPromocoes = new OleDbCommand(sqlConsultaPromocoesAtivas, conexao);
            OleDbDataReader drPromocoes = comandoConPromocoes.ExecuteReader();

            if (drPromocoes.HasRows)
            {
                ArrayList promocoes = new ArrayList();

                while (drPromocoes.Read())
                {
                    promocoes.Add(new { 
                        codPromocao = drPromocoes["cod_promocao"],
                        nomePromocao = drPromocoes["nome"]
                    });
                }

                cbPromocao.ValueMember = "codPromocao";
                cbPromocao.DisplayMember = "nomePromocao";
                cbPromocao.DataSource = promocoes;

            }
            else
            {
                cbPromocao.DataSource = null;
            }



            // Popula a combo de forma de pagamento
            OleDbCommand comandoConFormasPagamento = new OleDbCommand(sqlConsultaFormasPagamento, conexao);
            OleDbDataReader drFormasPagamento = comandoConFormasPagamento.ExecuteReader();

            if (drFormasPagamento.HasRows)
            {
                ArrayList formasPagamento = new ArrayList();
                while (drFormasPagamento.Read())
                {
                    formasPagamento.Add(new { 
                        codFP = drFormasPagamento["cod_forma_pagamento"],
                        descFP = drFormasPagamento["descricao"]
                    });
                }

                cbFormaPagamento.ValueMember = "codFP";
                cbFormaPagamento.DisplayMember = "descFP";
                cbFormaPagamento.DataSource = formasPagamento;
            }
            else
            {
                cbFormaPagamento.DataSource = null;
            }



            // Inicialmente a lbl fica escondida
            lblClienteEspecial.Hide();
            cbPromocao.SelectedItem = null;
            cbFormaPagamento.SelectedItem = null;


        }

      
        public void recebe(int codUsuario, int codVoo, string nomeVoo, string origem, string destino, string aeronave, string partida, string previsao, string nAssento, double valorVoo, int totalAssentos)
        {
            codUsuarioVenda = codUsuario;
            codVooSelecionado = codVoo;

            lblNomeVooValor.Text = nomeVoo;
            lblOrigemValor.Text = origem;
            lblDestinoValor.Text = destino;
            lblAeronaveValor.Text = aeronave;
            lblPartidaValor.Text = partida;
            lblPrevisaoValor.Text = previsao;
            lblNumAssentoValor.Text = nAssento;

            // Custo da venda é o valor total do voo dividido pelo total de assentos disponibilizados
            double custoVenda = valorVoo / totalAssentos;
            txtCustoVenda.Text = "R$ " + Math.Round(custoVenda, 2);

            // Valor de venda tem margem de 80%
            valorVenda = Math.Round(custoVenda * 1.80, 2);

            // Mostra o valor da margem
            lblMargemValor.Text = "R$ " + Math.Round((valorVenda - custoVenda), 2);

        }

        private void btnProcurarCliente_Click(object sender, EventArgs e)
        {
            // O usuário deverá selecionar o registro do cliente para realização da venda
            FrmConsultaCliente frmConCliente = new FrmConsultaCliente();
            frmConCliente.recebeDaVenda(this);
            frmConCliente.ShowDialog();

            // Se for um cliente especial, 
            // aplica-se um desconto fixo de R$ 99
            if (clienteEspecial)
            {
                lblDescClienteEspecialValor.Text = "R$ " + descontoFixoClienteEspecial;
            }
            else
            {
                lblDescClienteEspecialValor.Text = "R$ 00,00";
            }

        }

        private void FrmRealizaVenda_FormClosed(object sender, FormClosedEventArgs e)
        {
            conexao.Close();
        }

        private void txtValorVenda_KeyPress(object sender, KeyPressEventArgs e)
        {
            char ch = e.KeyChar;

            // Se o caractere a ser inserido é uma virgula (46 na tabela ascii)
            // e se a vírgula já existir a vírgula no texto
            // finaliza o evento sem inserir o novo caractere
            if (ch == 44 && txtValorVenda.Text.IndexOf(',') != -1)
            {
                e.Handled = true;
                return;
            }

            // Se o caractere a ser inserido não for um digito, não for uma vírgula e não for o backspace
            // finaliza o evento sem inserir
            if (!Char.IsDigit(ch) && ch != 8 && ch != 44)
            {
                e.Handled = true;
            }
        }

        private void btnVender_Click(object sender, EventArgs e)
        {

            if (valida()) 
            {
                try
                {
                    // Monta o comando de realização da venda
                    OleDbCommand comandoInserirVenda = new OleDbCommand(sqlInsereVenda, conexao);

                    OleDbParameter pNumAssento = new OleDbParameter("num_assento", OleDbType.Integer);
                    pNumAssento.Value = lblNumAssentoValor.Text;
                    comandoInserirVenda.Parameters.Add(pNumAssento);

                    OleDbParameter pFormaPagamento = new OleDbParameter("forma_pagamento", OleDbType.Integer);
                    pFormaPagamento.Value = cbFormaPagamento.SelectedValue;
                    comandoInserirVenda.Parameters.Add(pFormaPagamento);

                    // Calcula o valor da venda de acordo com a atribuição do cliente, especial ou não.
                    // Aplica-se o desconto da promoção também
                    double valorVendaComDescontos;
                    if (clienteEspecial)
                    {
                        valorVendaComDescontos = valorVenda - descontoFixoClienteEspecial - descontoPromocao;
                    }
                    else
                    {
                        valorVendaComDescontos = valorVenda - descontoPromocao;
                    }

                    txtValorVenda.Text = "R$ " + valorVendaComDescontos.ToString();
                    OleDbParameter pValor = new OleDbParameter("valor", OleDbType.Decimal);
                    pValor.Value = valorVendaComDescontos;
                    comandoInserirVenda.Parameters.Add(pValor);

                    OleDbParameter pCancelada = new OleDbParameter("flag_cancelada", OleDbType.VarChar);
                    pCancelada.Value = "n";
                    comandoInserirVenda.Parameters.Add(pCancelada);

                    OleDbParameter pCliente = new OleDbParameter("cod_cliente", OleDbType.Integer);
                    pCliente.Value = codClienteVenda;
                    comandoInserirVenda.Parameters.Add(pCliente);

                    OleDbParameter pUsuario = new OleDbParameter("cod_usuario", OleDbType.Integer);
                    pUsuario.Value = codUsuarioVenda;
                    comandoInserirVenda.Parameters.Add(pUsuario);

                    OleDbParameter pVoo = new OleDbParameter("cod_voo", OleDbType.Integer);
                    pVoo.Value = codVooSelecionado;
                    comandoInserirVenda.Parameters.Add(pVoo);

                    OleDbParameter pPromocao = new OleDbParameter("cod_promocao", OleDbType.Integer);
                    pPromocao.Value = cbPromocao.SelectedValue;
                    comandoInserirVenda.Parameters.Add(pPromocao);

                    // Insert da venda
                    try
                    {
                        comandoInserirVenda.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Não foi possível estabelecer conexão com o banco de dados.\n" + ex.Message);
                    }


                    // Faz o update do voo (descrementa a quantidade de assentos disponíveis)
                    OleDbCommand comandoUpdateVoo = new OleDbCommand(sqlUpdateQntAssentosVoo, conexao);

                    OleDbParameter pVooU1 = new OleDbParameter("cod_voo", OleDbType.Integer);
                    pVooU1.Value = codVooSelecionado;
                    comandoUpdateVoo.Parameters.Add(pVooU1);

                    OleDbParameter pVooU2 = new OleDbParameter("cod_voo", OleDbType.Integer);
                    pVooU2.Value = codVooSelecionado;
                    comandoUpdateVoo.Parameters.Add(pVooU2);

                    // Update
                    try
                    {
                        comandoUpdateVoo.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Não foi possível estabelecer conexão com o banco de dados.\n" + ex.Message);
                    }


                    MessageBox.Show(this, "Venda realizada com sucesso.", "Concretização venda",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                    Close();
                }
                catch (Exception)
                {
                    MessageBox.Show("Não foi possível se conectar ao banco de dados.");
                }

            }

        }

        public bool valida()
        {
            if (cbPromocao.SelectedItem == null)
            {
                MessageBox.Show(this, "Preencha o campo da promoção.", "Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                cbPromocao.Focus();
                cbPromocao.BackColor = Color.Tomato;
                return false;
            }
            else
                cbPromocao.BackColor = Color.White;


            if (cbFormaPagamento.SelectedItem == null)
            {
                MessageBox.Show(this, "Preencha o campo da forma de pagamento.", "Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                cbFormaPagamento.Focus();
                cbFormaPagamento.BackColor = Color.Tomato;
                return false;
            }
            else
                cbFormaPagamento.BackColor = Color.White;


            if (codClienteVenda == -1)
            {
                MessageBox.Show(this, "Selecione um cliente para vender.", "Validação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                //txtNomeCliente.Focus();
                txtNomeCliente.BackColor = Color.Tomato;
                txtCPFCliente.BackColor = Color.Tomato;
                return false;
            }
            else
            {
                txtNomeCliente.BackColor = Color.White;
                txtCPFCliente.BackColor = Color.White;
            }


            // Se chegar aqui validou
            return true;
        }

        private void cbPromocao_SelectionChangeCommitted(object sender, EventArgs e)
        {
            OleDbCommand comandoBuscaPromocao = new OleDbCommand(sqlConsultaPromocaoID, conexao);
            
            OleDbParameter pCod = new OleDbParameter("cod_promocao", OleDbType.Integer);
            pCod.Value = cbPromocao.SelectedValue;
            comandoBuscaPromocao.Parameters.Add(pCod);

            OleDbDataReader dr = comandoBuscaPromocao.ExecuteReader();

            if (dr.Read())
            { 
                descontoPromocao = Double.Parse(dr["desconto"].ToString());
            }

            lblDescPromocaoValor.Text = "R$ " + descontoPromocao;

        }

        private void btnCalcularVenda_Click(object sender, EventArgs e)
        {
            // Calcula o valor da venda de acordo com a atribuição do cliente, especial ou não.
            // Aplica-se o desconto da promoção também
            double valorVendaComDescontos;
            if (clienteEspecial)
            {
                valorVendaComDescontos = valorVenda - descontoFixoClienteEspecial - descontoPromocao;
            }
            else
            {
                valorVendaComDescontos = valorVenda - descontoPromocao;
            }

            txtValorVenda.Text = "R$ " + valorVendaComDescontos.ToString();


        }

        private void FrmRealizaVenda_KeyDown(object sender, KeyEventArgs e)
        {
            //Hotkey para a tecla ESC fechar a janela
            if (e.KeyData == (Keys.Escape))
            {
                this.Close();
            }

            //Hotkey para salvar os dados
            if (e.KeyData == (Keys.Control | Keys.S))
            {
                btnVender_Click(sender, e);
            }
        }
    }
}
